﻿
#if defined(_MSC_VER) /*&& defined(_WIN32) && defined(WIN32)*/
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

// SDL 关闭了也可以 除去 4996 的警告 (/错误)
#pragma warning(disable:4996)
#include <WinSock2.h>

#pragma comment(lib, "ws2_32")
#elif defined(unix) || defined(__unix) || defined(__unix__)
//#warning You are using UNIX
#elif defined(__APPLE__) || defined(__MACH__)
//#warning You are using Mac OS X
#elif defined(__linux__)
//#warning You are using Linux
#elif defined(__FreeBSD__)
//#warning You are using FreeBSD
#else
#error Unknown OS
#endif

#include <stdio.h>

const unsigned short SERVER_PORT = 4444;


int main(int argc, const char* argv[])
{
#if defined(_MSC_VER) && defined(_WIN32) && defined(WIN32) 
    WORD wVer = MAKEWORD(2, 2);
    WSADATA data;
    WSAStartup(wVer, &data);
#endif

    SOCKET _sock = INVALID_SOCKET;
    SOCKET _cSock = INVALID_SOCKET;
    int nret = 0;

    do
    {
        _sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (INVALID_SOCKET == _sock) {
            printf("socket函数调用失败\n");
            break;
        }

        sockaddr_in _sin;
        _sin.sin_family = AF_INET;
        _sin.sin_port = htons(SERVER_PORT);
        _sin.sin_addr.S_un.S_addr = inet_addr("0.0.0.0");//INADDR_ANY

        nret = bind(_sock, (sockaddr*)&_sin, sizeof(sockaddr_in));
        if (SOCKET_ERROR == nret) {
            printf("bind 失败\n");
            break;
        }

        nret = listen(_sock, 5); //SOMAXCONN,  SOMAXCONN_HINT(  number )
        if (SOCKET_ERROR == nret) {
            printf("listen 失败\n");
            break;
        }

        sockaddr_in clientSocket;
        int addrLen = 0;
        
        addrLen = (int)sizeof(sockaddr_in);
        _cSock = accept(_sock, (sockaddr*)&clientSocket, &addrLen);
        if (INVALID_SOCKET == _cSock) {
            printf("accept 失败\n");
            break;
        }
        // inet_ntoa 这个函数应该是使用了静态变量
        char* ipClient = inet_ntoa(clientSocket.sin_addr);
        unsigned short cPort = ntohs(clientSocket.sin_port);
        printf("已接受客户端( %s:%d )的连接.\n", ipClient, cPort);

        char _recvBuff[128];
        while (TRUE)
        {
            nret = recv(_cSock, _recvBuff, sizeof(_recvBuff), 0);
            if (SOCKET_ERROR == nret) {
                printf("recv(_cSock ) 失败.\n");
                break;
            }
            else if (0 == nret) {
                printf("客户端 socket 已关闭(gracefully closed).\n");
                closesocket(_cSock);
                _cSock = INVALID_SOCKET;
                continue;
            }

            printf("接收到的命令：[ %s ].\n", _recvBuff);

            if (0 == stricmp(_recvBuff, "exit")) {
                printf("客户端已退出.\n");
                closesocket(_cSock);
                _cSock = INVALID_SOCKET;
                continue;
            }
            else if (0 == stricmp(_recvBuff, "getName")) {
                char msgBuf[] = "小强哦";
                nret = send(_cSock, msgBuf, sizeof(msgBuf), 0);
            }
            else {
                char msgBuf[] = "???.我是服务器.";
                nret = send(_cSock, msgBuf, sizeof(msgBuf), 0);
            }
        }

        if (INVALID_SOCKET != _cSock)
            closesocket(_cSock);

    } while (0);

    if (INVALID_SOCKET != _sock)
        closesocket(_sock);

#if defined(_WIN32) && defined(WIN32) && defined(_MSC_VER)
    WSACleanup();
#endif
    printf("程序退出...\n");
    getchar();
    return 0;
}